package com.future.bs.component.stream;

import com.future.bs.component.business.Business;
import com.future.bs.context.Context;
import com.future.bs.component.report.DefaultReport;
import com.future.bs.component.report.Report;
import com.future.bs.context.BusinessStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 串行业务流
 * </p>
 *
 * @author Jingjie
 * @since 2020-11-08 09:55
 */
public class SequentialStream<T extends Context> extends Stream<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(SequentialStream.class);

    private List<Business<T>> businesses;

    @Override
    public Report<T> execute(T context) {
        Report<T> report = null;
        for (Business<T> business : businesses) {
            report = business.execute(context);
            if (report != null && BusinessStatus.FAILED == report.getStatus()) {
                LOGGER.warn("Business Stream '{}' has failed, skipping follower business units.", getName());
                return report;
            }
        }
        return report == null ? new DefaultReport<>(BusinessStatus.SUCCESS, context) : report;
    }

    /**
     * <p>
     * 建造器
     * </p>
     *
     * @author Jingjie
     * @since 2020-11-08 09:55
     */
    public class Builder {
        private String name;
        private List<Business<T>> businesses = new ArrayList<>();

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder process(Business<T> business) {
            this.businesses.add(business);
            return this;
        }

        public Builder process(List<Business<T>> businesses) {
            this.businesses.addAll(businesses);
            return this;
        }

        public SequentialStream<T> build() {
            SequentialStream.this.name = this.name;
            SequentialStream.this.businesses = this.businesses;
            return SequentialStream.this;
        }
    }
}
